/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */

use std::time::Duration;

use super::*;

const DEFAULT_QUEUE: &'static str = "dq";
const DEFAULT_SUFFIX: &'static str = "";

#[derive(Clone)]
pub struct RssBuilder {
    pub queue: String,
    pub server: Server,
    pub callback: CallbackFunc,
    pub suffix: String,
    pub parallel: bool,
    pub dial_timeout: Option<Duration>,
}

impl Default for RssBuilder {
    fn default() -> Self {
        Self {
            queue: Default::default(),
            server: Default::default(),
            callback: Arc::new(default_callback),
            suffix: Default::default(),
            parallel: Default::default(),
            dial_timeout: Default::default(),
        }
    }
}

impl RssBuilder {
    pub fn new(server: Server) -> Self {
        let mut parallel = true;
        if let Some(serial) = server.serial {
            if serial {
                parallel = false;
            }
        }
        Self {
            queue: DEFAULT_QUEUE.into(),
            server: server,
            callback: Arc::new(default_callback),
            suffix: DEFAULT_SUFFIX.into(),
            parallel: parallel,
            dial_timeout: None,
        }
    }
    pub fn set_queue(&mut self, queue: String) -> &mut Self {
        self.queue = queue;
        self
    }

    pub fn set_server(&mut self, server: Server) -> &mut Self {
        self.server = server;
        self
    }

    pub fn set_callback(&mut self, callback: CallbackFunc) -> &mut Self {
        self.callback = callback;
        self
    }

    pub fn set_suffix(&mut self, suffix: String) -> &mut Self {
        self.suffix = suffix;
        self
    }

    pub fn set_parallel(&mut self, parallel: bool) -> &mut Self {
        self.parallel = parallel;
        self
    }

    pub fn set_dial_timeout(&mut self, dial_timeout: Duration) -> &mut Self {
        self.dial_timeout = Some(dial_timeout);
        self
    }
    pub fn build(&self) -> RssBuilder {
        RssBuilder {
            queue: self.queue.clone(),
            server: self.server.clone(),
            callback: self.callback.clone(),
            suffix: self.suffix.clone(),
            parallel: self.parallel.clone(),
            dial_timeout: self.dial_timeout.clone(),
        }
    }
}

pub struct ReqBuilder {
    pub queue: String,
    pub suffix: String,
    pub server: Option<Server>,
    pub req: Option<Vec<u8>>,
    pub resp: Option<Vec<u8>>,
    pub server_type: String,
    pub dial_timeout: Option<Duration>,
}

impl ReqBuilder {
    pub fn new(server: Option<Server>) -> Self {
        let mut server_type = "".to_string();
        if let Some(s) = &server {
            server_type = s.server_type.to_owned();
        }
        Self {
            queue: DEFAULT_QUEUE.into(),
            suffix: DEFAULT_SUFFIX.into(),
            server,
            req: None,
            resp: None,
            server_type,
            dial_timeout: None,
        }
    }
    pub fn set_queue(&mut self, queue: String) -> &mut Self {
        self.queue = queue;
        self
    }

    pub fn set_suffix(&mut self, suffix: String) -> &mut Self {
        self.suffix = suffix;
        self
    }

    pub fn set_server(&mut self, server: Server) -> &mut Self {
        self.server = Some(server);
        self
    }

    pub fn set_req(&mut self, req: Vec<u8>) -> &mut Self {
        self.req = Some(req);
        self
    }

    pub fn set_resp(&mut self, resp: Vec<u8>) -> &mut Self {
        self.resp = Some(resp);
        self
    }

    pub fn set_server_type(&mut self, server_type: String) -> &mut Self {
        self.server_type = server_type;
        self
    }

    pub fn set_dial_timeout(&mut self, dial_timeout: Duration) -> &mut Self {
        self.dial_timeout = Some(dial_timeout);
        self
    }
    pub fn build(&self) -> Self {
        let mut req: Option<Vec<u8>> = None;
        if let Some(r) = &self.req {
            req = Some(r.clone());
        }
        let mut resp: Option<Vec<u8>> = None;
        if let Some(r) = &self.resp {
            resp = Some(r.clone());
        }
        Self {
            queue: self.queue.clone(),
            suffix: self.suffix.clone(),
            server: self.server.clone(),
            req,
            resp,
            server_type: self.server_type.clone(),
            dial_timeout: self.dial_timeout.clone(),
        }
    }
}
